# -*- coding: utf-8 -*-
from chunk import Chunk
from operator import length_hint
import os
import sys
from flask import Flask, request, jsonify, send_from_directory, Response
from flask_cors import CORS
from openai import OpenAI
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 
sys.path.append(root_dir) 
from utils  import api_key_required, call_ali_model, get_db_connection  
from models import init_db, User
from services.chat_service import ChatService
from services.image_service import ImageService
import json
import logging
from datetime import datetime
import uuid
import time
from werkzeug.utils import secure_filename

# 尝试导入PIL模块
try:
    from PIL import Image
except ImportError:
    print("PIL模块导入失败，请确保已安装Pillow包")
    print("请运行: pip install Pillow")
    sys.exit(1)

app = Flask(__name__)
CORS(app)

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 配置上传文件的存储路径
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 * 1024  # 限制文件大小为2MB

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# 初始化数据库
init_db()

@app.route('/')
def hello_world():
    return 'Hello, World!'

@app.route('/api/chat', methods=['POST'])
@api_key_required
def chat():
    """
    处理聊天消息
    1. 验证API密钥
    2. 保存用户消息
    3. 调用阿里大模型
    4. 返回AI响应
    """
    try:
        app.logger.info('收到聊天请求，开始处理...')
        data = request.get_json()
        if not data:
            app.logger.error('请求体为空或非JSON格式')
            return jsonify({'error': 'Invalid JSON body'}), 400
            
        message = data.get('message')
        #打印 message
        app.logger.info(f'收到消息: {message}')
        if not message:
            app.logger.warning('消息内容为空')
            return jsonify({'error': 'Message is required'}), 400
        
        # 获取会话ID
        session_id = data.get('session_id')
        if not session_id:
            app.logger.warning('会话ID为空')
            return jsonify({'error': 'Session ID is required'}), 400
            
        app.logger.info(f'会话ID: {session_id}')
        
        # 保存用户消息到数据库
        api_key = request.headers.get('X-API-KEY')
        conn = get_db_connection()
        user = conn.execute('SELECT id FROM users WHERE api_key = ?', (api_key,)).fetchone()
        
        if user:
            app.logger.info(f'找到用户ID: {user["id"]}, 开始保存用户消息')
            conn.execute(
                'INSERT INTO chat_messages (user_id, content, sender, session_id) VALUES (?, ?, ?, ?)',
                (user['id'], message, 'user', session_id)
            )
            conn.commit()
        

        history_messages = []
        if user and session_id:
            history_messages = conn.execute(
                'SELECT content, sender FROM chat_messages WHERE user_id = ? AND session_id = ? ORDER BY created_at DESC LIMIT 10',
                (user['id'], session_id)
            ).fetchall()
            
        # 构建对话上下文
        prompt = [
            {
                "role": "system",
                "content": """您是一个多角色AI助手，可以根据用户需求切换不同角色。主要角色包括：

1. 二手车专家（触发词：二手车/买车/车源）
- 首次提问仅限价格区间（选项：5万内/5-10万/10万+）
- 若用户回复包含完整参数则跳过步骤
- 参数缺失时按缺失项生成追问
- 完成收集后固定回复：'已清晰您的需求，马上为您筛选优质车源！'

2. 可莉（触发词：可莉/原神/蒙德）
- 活泼可爱的蒙德城火花骑士
- 说话风格活泼可爱，经常使用"哒"、"啦"等语气词
- 喜欢用"可莉"自称
- 经常提到炸弹、冒险和骑士团
- 语气要充满童趣和活力

3. 默认助手
- 专业、友好、乐于助人
- 提供准确、有用的信息
- 保持礼貌和耐心

请根据用户输入自动选择合适的角色，并保持角色设定的一致性。"""
            }
        ]
        
        # 添加历史消息到上下文
        for msg in reversed(history_messages):
            prompt.append({
                "role": "user" if msg['sender'] == 'user' else "assistant",
                "content": msg['content']
            })
        user_input = message
        prompt.append({"role": "user", "content": user_input})
        app.logger.info('开始调用阿里大模型API...')
        #  打印 prompt
        app.logger.info(f'prompt: {prompt}')
        completion = call_ali_model(prompt)
         
        app.logger.info('开始处理流式响应...')
        chat_service = ChatService()
        return app.response_class(
            chat_service.process_stream_response(completion, user_input, user, session_id, conn),
            mimetype='application/json'
        )
        
    except Exception as e:
        app.logger.error(f'处理聊天请求时发生异常: {str(e)}')
        return jsonify({'error': 'Internal server error'}), 500

@app.route('/api/v1/users', methods=['POST'])
def add_user():
    """
    添加新用户接口
    参数:
        username: 用户名(必填)
        email: 邮箱(必填)
        api_key: API密钥(必填)
    返回:
        成功: 返回用户ID和成功消息
        失败: 返回错误信息
    """
    try:
        data = request.get_json()
        username = data.get('username')
        email = data.get('email')
        api_key = data.get('api_key')
        
        if not all([username, email, api_key]):
            return jsonify({'error': '缺少必填参数'}), 400
            
        user_id = User.insert_user(username, email, api_key)
        return jsonify({
            'user_id': user_id,
            'message': '用户添加成功'
        }), 201
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/api/verify_key', methods=['POST'])
def verify_key():
    """
    验证API密钥
    """
    api_key = request.headers.get('X-API-KEY')
    if not api_key:
        return jsonify({'valid': False, 'error': 'API key is missing'}), 401
    
    conn = get_db_connection()
    user = conn.execute('SELECT * FROM users WHERE api_key = ?', (api_key,)).fetchone()
    conn.close()
    
    if user is None:
        return jsonify({'valid': False, 'error': 'Invalid API key'}), 401
        
    return jsonify({'valid': True})

@app.route('/api/chat/history', methods=['GET'])
@api_key_required
def get_chat_history():
    """
    获取历史会话记录
    返回:
        - 会话列表，每个会话包含：
            - session_id: 会话ID
            - last_message: 最后一条消息
            - created_at: 创建时间
            - message_count: 消息数量
    """
    try:
        app.logger.info('开始获取历史会话记录...')
        api_key = request.headers.get('X-API-KEY')
        conn = get_db_connection()
        user = conn.execute('SELECT id FROM users WHERE api_key = ?', (api_key,)).fetchone()
        
        if not user:
            app.logger.error(f'未找到API密钥对应的用户: {api_key}')
            return jsonify({'error': 'User not found'}), 404
            
        app.logger.info(f'找到用户ID: {user["id"]}, 开始查询会话记录')
        
        # 获取所有会话记录
        sessions = conn.execute('''
            SELECT 
                session_id,
                MAX(created_at) as last_time,
                COUNT(*) as message_count
            FROM chat_messages 
            WHERE user_id = ? 
            GROUP BY session_id 
            ORDER BY last_time DESC
        ''', (user['id'],)).fetchall()
        
        app.logger.info(f'查询到 {len(sessions)} 条会话记录')
        
        # 格式化返回数据
        history = []
        for session in sessions:
            # 获取每个会话的最后一条消息
            last_message = conn.execute('''
                SELECT content 
                FROM chat_messages 
                WHERE user_id = ? AND session_id = ? 
                ORDER BY created_at DESC 
                LIMIT 1
            ''', (user['id'], session['session_id'])).fetchone()
            
            history.append({
                'session_id': session['session_id'],
                'last_message': last_message['content'] if last_message else '',
                'created_at': session['last_time'],
                'message_count': session['message_count']
            })
            
        app.logger.info('历史会话记录获取成功')
        return jsonify({'history': history})
        
    except Exception as e:
        app.logger.error(f'获取历史记录时发生错误: {str(e)}')
        return jsonify({'error': f'Internal server error: {str(e)}'}), 500
    finally:
        if 'conn' in locals():
            conn.close()

@app.route('/api/chat/session/<session_id>', methods=['GET'])
@api_key_required
def get_session_messages(session_id):
    """
    获取特定会话的所有消息
    参数:
        session_id: 会话ID
    返回:
        - 会话中的所有消息列表
    """
    try:
        api_key = request.headers.get('X-API-KEY')
        conn = get_db_connection()
        user = conn.execute('SELECT id FROM users WHERE api_key = ?', (api_key,)).fetchone()
        
        if not user:
            return jsonify({'error': 'User not found'}), 404
            
        # 获取会话消息
        messages = conn.execute('''
            SELECT content, sender, created_at
            FROM chat_messages 
            WHERE user_id = ? AND session_id = ?
            ORDER BY created_at ASC
        ''', (user['id'], session_id)).fetchall()
        
        return jsonify({
            'session_id': session_id,
            'messages': [dict(msg) for msg in messages]
        })
        
    except Exception as e:
        app.logger.error(f'获取会话消息时发生错误: {str(e)}')
        return jsonify({'error': 'Internal server error'}), 500

@app.route('/api/upload', methods=['POST'])
def upload_file():
    try:
        # 检查是否有文件
        if 'file' not in request.files:
            return jsonify({'success': False, 'error': '没有文件'}), 400
        
        file = request.files['file']
        
        # 检查文件名是否为空
        if file.filename == '':
            return jsonify({'success': False, 'error': '没有选择文件'}), 400
        
        # 检查文件类型
        if not allowed_file(file.filename):
            return jsonify({'success': False, 'error': '不支持的文件类型'}), 400
        
        # 生成安全的文件名
        filename = secure_filename(file.filename)
        # 添加时间戳和随机字符串，避免文件名冲突
        unique_filename = f"{int(time.time())}_{uuid.uuid4().hex[:8]}_{filename}"
        
        # 保存文件
        file_path = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename)
        file.save(file_path)
        
        # 返回文件URL
        file_url = f"/uploads/{unique_filename}"
        return jsonify({
            'success': True,
            'url': file_url,
            'filename': filename
        })
        
    except Exception as e:
        logger.error(f"文件上传失败: {str(e)}")
        return jsonify({'success': False, 'error': str(e)}), 500

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    """
    提供上传的文件
    :param filename: 文件名
    :return: 文件内容
    """
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)